﻿using System;
using System.Collections.Generic;
using System.Drawing.Printing;
using System.IO;
using System.Linq;
using System.Text;
using Microsoft.Reporting.WinForms;
using System.Drawing;

namespace DblogStudio.Utils
{
    class PrintUtil
    {
        public static string WORDFORMAT = "WORD";
        public static string PDFFORMAT = "PDF";
        public static string EXCELFORMAT = "EXCEL";
        /// <summary>
        /// Lấy tên máy in mặc định
        /// </summary>
        /// <returns></returns>
        public static string GetDefaultPrinter()
        {
            PrinterSettings settings = new PrinterSettings();
            foreach (string printer in PrinterSettings.InstalledPrinters)
            {
                settings.PrinterName = printer;
                if (settings.IsDefaultPrinter)
                    return printer;
            }
            return string.Empty;
        }

        /// <summary>
        /// Xuất dữ liệu trong report ra file
        /// </summary>
        /// <param name="report">Dữ liệu sẽ xuất ra</param>
        /// <param name="typeDoc">Kiểu tài liệu muốn xuaart {PDF, WORD, IMAGE, EXCEL}</param>
        /// <param name="fileName">Đường dẫn tạm thời để lưu file</param>
        public static void Export(LocalReport report, string typeDoc, string fileName)
        {
            string deviceInfo =
              "<DeviceInfo>" +
              "  <OutputFormat>EMF</OutputFormat>" +
              "  <PageWidth>8.27in</PageWidth>" +
              "  <PageHeight>11.7in</PageHeight>" +
              "  <MarginTop>0.3in</MarginTop>" +
              "  <MarginLeft>0.2in</MarginLeft>" +
              "  <MarginRight>0.2in</MarginRight>" +
              "  <MarginBottom>0.2in</MarginBottom>" +
              "</DeviceInfo>";
            var bytes = report.Render(typeDoc, deviceInfo);
            using (var fs = new FileStream(fileName, FileMode.Create))
            {
                fs.Write(bytes, 0, bytes.Length);
                fs.Close();
            }
        }

        public enum DocType { Pdf, Word, Excel, Image };

        public static void DoExport(LocalReport report, DocType enumDocType, string fileName, bool landscape = false)
        {
            var deviceInfo = landscape ? DEFAULT_DEVICE_INFO_STRING_A4_LANDSCAPE : DEFAULT_DEVICE_INFO_STRING_A4;
            string docType;
            if (enumDocType == DocType.Excel)
                docType = "Excel";
            else if (enumDocType == DocType.Image)
                docType = "Image";
            else if (enumDocType == DocType.Word)
                docType = "Word";
            else
                docType = "PDF";
            var bytes = report.Render(docType, deviceInfo);
            using (var fs = new FileStream(fileName, FileMode.Create))
            {
                fs.Write(bytes, 0, bytes.Length);
                fs.Close();
            }
        }

        public const string DEFAULT_DEVICE_INFO_STRING_A4 =
            @"<DeviceInfo>
                <OutputFormat>EMF</OutputFormat>
                <PageWidth>8.27in</PageWidth>
                <PageHeight>11.69in</PageHeight>
                <MarginTop>0.25in</MarginTop>
                <MarginLeft>0.25in</MarginLeft>
                <MarginRight>0.25in</MarginRight>
                <MarginBottom>0.25in</MarginBottom>
            </DeviceInfo>";

        public const string DEFAULT_DEVICE_INFO_STRING_A4_LANDSCAPE =
            @"<DeviceInfo>
                <OutputFormat>EMF</OutputFormat>
                <PageWidth>11.69in</PageWidth>
                <PageHeight>8.5in</PageHeight>
                <MarginTop>0.025in</MarginTop>
                <MarginLeft>0.25in</MarginLeft>
                <MarginRight>0.25in</MarginRight>
                <MarginBottom>0.025in</MarginBottom>
            </DeviceInfo>";

        public static void DoPrint(LocalReport report, bool landscape = false)
        {
            var deviceInfo = landscape ? DEFAULT_DEVICE_INFO_STRING_A4_LANDSCAPE : DEFAULT_DEVICE_INFO_STRING_A4;
            Warning[] warnings;
            var m_streams = new List<Stream>();
            report.Render("Image", deviceInfo,
                (aName, aFileNameExtension, aEncoding, aMimeType, aWillSeek) =>
                {
                    Stream stream = new MemoryStream();
                    m_streams.Add(stream);
                    return stream;
                },
               out warnings);
            foreach (Stream stream in m_streams)
                stream.Position = 0;

            int m_currentPageIndex = 0;
            if (m_streams == null || m_streams.Count == 0)
                throw new Exception("Lỗi: Không có dữ liệu để in.");
            PrintDocument printDoc = new PrintDocument();
            printDoc.DefaultPageSettings.Landscape = landscape;
            //printDoc.PrinterSettings.PrinterName = "";
            if (!printDoc.PrinterSettings.IsValid)
            {
                throw new Exception("Lỗi: Không tìm thấy máy in hoặc chưa thiết lập máy in mặc định.");
            }
            else
            {
                printDoc.PrintPage += new PrintPageEventHandler((oSender, ev) =>
                {
                    using (var pageImage = new System.Drawing.Imaging.Metafile(m_streams[m_currentPageIndex]))
                    {
                        //System.Console.WriteLine("In trang " + m_currentPageIndex + "...");
                        // Adjust rectangular area with printer margins.
                        var adjustedRect = new Rectangle(
                            ev.PageBounds.Left - (int)ev.PageSettings.HardMarginX,
                            ev.PageBounds.Top - (int)ev.PageSettings.HardMarginY,
                            ev.PageBounds.Width,
                            ev.PageBounds.Height);

                        // Draw a white background for the report
                        ev.Graphics.FillRectangle(Brushes.White, adjustedRect);

                        // Draw the report content
                        ev.Graphics.DrawImage(pageImage, adjustedRect);

                        try
                        {
                            m_streams[m_currentPageIndex].Close();
                            //System.Console.WriteLine("Đã giải phóng bộ nhớ dành cho trang " + m_currentPageIndex);
                        }
                        catch (Exception exc)
                        {
                            //System.Console.WriteLine("Lỗi khi giải phóng bộ nhớ dành cho trang " + m_currentPageIndex + ": " + exc);
                        }
                    }

                    // Prepare for the next page. Make sure we haven't hit the end.
                    m_currentPageIndex++;
                    ev.HasMorePages = (m_currentPageIndex < m_streams.Count);
                });
                printDoc.EndPrint += (oSender, ev) =>
                {
                    //for (int i = 0; i < m_streams.Count; i++)
                    //{
                    //    var stream = m_streams[i];
                    //    stream.Close();
                    //    stream.Dispose();
                    //}
                };
                m_currentPageIndex = 0;

                printDoc.Print();
            }
        }
    }
}
